package com.lbiuse.wx.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;

/**
 * 签名工具
 */
@Slf4j
public class SignUtils {

    /**
     * 对所有待签名参数按照字段名的ASCII
     * 码从小到大排序（字典序）后，使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1
     * 。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密，字段名和字段值都采用原始值，不进行URL 转义。
     *
     * @param params 参与签名的键值对
     * @return 签名后得到的signature
     */
    public static String sha1Sign(Map<String, String> params) {
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        StringBuilder builder = new StringBuilder(keys[0]);
        builder.append("=").append(params.get(keys[0].toLowerCase()));
        for (int i = 1; i < keys.length; i++) {
            builder.append("&").append(keys[i].toLowerCase()).append("=")
                    .append(params.get(keys[i]));
        }
        return DigestUtils.sha1Hex(builder.toString());
    }

    /**
     * 对所有待签名参数按照字段名的ASCII
     * 码从小到大排序（字典序）后，使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串string1
     * 再拼接店铺的秘钥
     * 对string1作MD5加密，字段名和字段值都采用原始值，不进行URL 转义。
     *
     * @param treeMap 参与签名的键值对
     * @return 签名后得到的signature
     */
    public static String paySign(TreeMap<String, String> treeMap) {
        StringBuilder sb = new StringBuilder();
        for (String key : treeMap.keySet()) {
            if (StringUtils.isNotEmpty(treeMap.get(key))) {
                sb.append(key).append("=").append(treeMap.get(key)).append("&");
            }
        }
        sb.append("key=" + WechatConfigUtil.getShopSecrect());
        String sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
        return sign;
    }

}
